<?php
/**
 * System_Globals - класс, который содержит все необходимые для работы приложения функции
 *     (методы) и свойства (например подключение к базе данных и пр.), т.е. все 
 *     необходимое собрано в одном месте для дальнейшего использования.
 *
 * LICENSE: Free to use license
 * 
 * @copyright 	2009
 * @author 		Яковлев Иван Yak1980@list.ru | Best4u.mail@gmail.com
 * @version		$id:$
 * @link 
 * @since 
 */
class System_Globals 
{
	// указатель для хранения подключения к базе данных:
	private static $_db = null;

	// создаем контейнер для хранения кешированных файлов нашего приложения:
	private static $_cacheCore = null;

	// массив соответсвий расширений файлов значаниям иконки и mime типа файла
	private static $_extArray = array(
    	//'default' 	=> array('file-24x24.png', 			'text/html'),	
		'default' 		=> array('file-24x24.png',			'application/applefile'),	
    	'emptyFolder' 	=> array('folder-empty-24x24.png',	'application/applefile'),
    	'folder' 		=> array('folder-24x24.png',		'application/applefile'),
    	'7z' 			=> array('7zip-24x24.png',			'application/x-7z-compressed'),
    	'ace' 			=> array('zip-24x24.png',			'application/x-ace-compressed'),
    	'avi'			=> array('video-24x24.png',			'video/avi'),
    	'bat' 			=> array('dll-24x24.png',			'text/plain'),
    	'bmp'			=> array('img-24x24.png',			'image/bmp'),
    	'cab' 			=> array('zip-24x24.png',			'application/vnd.ms-cab-compressed'),
    	'chm'			=> array('html-24x24.png',			'application/applefile'),
    	'cmd'			=> array('cmd-24x24.png',			'application/applefile'),
    	'csv'			=> array('txt-24x24.png',			'application/vnd.ms-excel'),
    	'dat'			=> array('video-24x24.png',			'application/applefile'),
    	'djv'			=> array('html-24x24.png',			'image/vnd.djvu'),
    	'djvu'			=> array('html-24x24.png',			'image/vnd.djvu'),
    	'dll' 			=> array('dll-24x24.png',			'application/applefile'),
    	'doc'		 	=> array('MS-Word-2-24x24.png',		'application/msword'),
    	'docx'		 	=> array('MS-Word-2-24x24.png',		'application/msword'),
    	'exe' 			=> array('exe-24x24.png',			'application/applefile'),
    	'gif'			=> array('img-24x24.png',			'image/gif'),
    	'html' 			=> array('html-24x24.png',			'text/html'),
    	'htm' 			=> array('html-24x24.png',			'text/html'),
    	'ico'			=> array('img-24x24.png', 			'image/x-icon'),
    	'ini' 			=> array('ini-24x24.png', 			'text/plain'),
    	'jpe'			=> array('img-24x24.png', 			'image/jpeg'),
    	'jpeg'			=> array('img-24x24.png', 			'image/jpeg'),
    	'jpg'			=> array('img-24x24.png', 			'image/jpeg'),
    	'mht' 			=> array('html-24x24.png', 			'message/rfc822'),
    	'mid' 			=> array('mp3-24x24.png', 			'audio/midi'),
    	'mov'			=> array('video-24x24.png', 		'video/quicktime'),
    	'mp2' 			=> array('mp3-24x24.png', 			'audio/mpeg'),
    	'mp3' 			=> array('mp3-24x24.png', 			'audio/mpeg'),
    	'mp4'			=> array('video-24x24.png', 		'video/mpeg'),
    	'mpg4'			=> array('video-24x24.png', 		'video/mpeg'),
    	'mpg'			=> array('video-24x24.png', 		'video/mpeg'),
    	'pdf' 			=> array('Adobe-24x24.png', 		'application/pdf'),
    	'png'			=> array('img-24x24.png', 			'image/x-png'),
    	'ppt' 			=> array('PowerPoint-24x24.png', 	'application/vnd.ms-powerpoint'),
    	'r00' 			=> array('zip-24x24.png', 			'application/x-rar-compressed'),
    	'r01' 			=> array('zip-24x24.png', 			'application/x-rar-compressed'),
    	'rar' 			=> array('zip-24x24.png', 			'application/x-rar-compressed'),
    	'rtf' 			=> array('MS-Word-2-24x24.png', 	'text/rtf'),
    	'tif'			=> array('img-24x24.png', 			'image/tiff'),
    	'txt' 			=> array('txt-24x24.png', 			'text/plain'),
    	'xls' 			=> array('Excel-24x24.png', 		'application/vnd.ms-excel'),
    	'xlsx' 			=> array('Excel-24x24.png', 		'application/vnd.ms-excel'),
    	'wav'			=> array('mp3-24x24.png', 			'audio/wav'),
    	'wmv'			=> array('WMP-24x24.png', 			'video/x-ms-wmv'),
    	'zip' 			=> array('zip-24x24.png', 			'application/x-zip-compressed')
    );
	// используется для преобразования числа месяца в его название
	public static $monthTranslate = array (
		1 	=> 'января',
		2 	=> 'февраля',
		3 	=> 'марта',
		4 	=> 'апреля',
		5 	=> 'мая',
		6 	=> 'июня',
		7 	=> 'июля',
		8 	=> 'августа',
		9 	=> 'сентября',
		10 	=> 'октября',
		11 	=> 'ноября',
		12 	=> 'декабря'
	);
	
	
	/**
	 * Here, we create a class that cannot be instantiated from outside of itself. 
	 * That may sound difficult, but it’s simply a matter of defining a private constructor
	 * 
	 * Unlike a normal class, a singleton class cannot be directly instantiated within other classes.
	 * Instead, a singleton class may instantiate only itself. To achieve this restriction, 
	 * the __construct() method must be marked private. If you try to construct 
	 * a class with a private constructor, you will get an accessibility level error.
	 */
	private function __construct()
	{
		// constructor
	}
	
	
	/**
	 * the private __clone() and _wakeup() method closes a small loophole in the PHP language that could make a
	 * copy of the object and defeat singleton responsibility.
	 */
	private function __clone()
	{
	    trigger_error('Клонирование объекта запрещено!' . E_USER_ERROR);
	}
	private function __wakeup()
	{
		trigger_error('Десериализация объекта запрещена!' . E_USER_ERROR);
	}

	
	/**
	 * Подключение к базе данных - альтернативный способ без использования реестра
	 */
	static public function getDBConnection()
	{
		/**
		 * Шаг 1: Если уже было установленно подключение к БД, то возвращаем его
		 */
		if (self::$_db !== null) return self::$_db;
		
		/**
		 * Шаг 2: Если подключения к БД еще не производилось, то подключаемся к базе
		 */
		// берем из реестра настройки конфигурации
		$config = Zend_Registry::get('config');
		
		// задаем параметры подключения к базе данных
		$params = array('host' 		=> $config->database->hostname,
						'username' 	=> $config->database->username,
						'password'	=> $config->database->password,
						'dbname'	=> $config->database->database);
		
		// Создание экземпляра класса адаптера не приведет к немедленному соединению с сервером СУРБД. 
		// Адаптер сохраняет параметры соединения и производит подключение, когда нужно произвести первый  
		// запрос к БД. Это значит, что само по себе создание объекта адаптера производится быстро и  
		// занимает мало ресурсов. Вы можете создавать экземпляр адаптера даже в том случае, 
		// если не уверены в том, что текущий запрос к вашему приложению требует каких-либо действий с БД:
		self::$_db = Zend_Db::factory($config->database->type, $params);
		Zend_Db_Table::setDefaultAdapter(self::$_db);
		
		// Если нужно принудительно создать соединение с СУРБД, то используйте метод getConnection(). 
		// Этот метод возвращает объект соединения в представлении соответствующего 
		// расширения PHP для баз данных:
		//self::$_db->getConnection();
		
		return self::$_db;
	}

	
	/**
	 * getCacheCore() - метод возвращяающий данные из кеша или заносящий их в кеш
	 */
	static public function getCacheCore()
	{
		/**
		 * Шаг 1: Если уже было произведено кеширование, то возвращаем кешированные данные
		 */
		if (self::$_cacheCore !== null) return self::$_cacheCore;
		
		/**
		 * Шаг 2: Если кеш еще не создавался или актуальность его истекла, то заново производим кеширование
		 */
		// берем из реестра настройки конфигурации
		$config = Zend_Registry::get('config');
		
		// задаем опции фронтэнда:
		$frontendOptions = array(
			'lifetime'=>7200, // время жизни кэша - 2 часа
			'automatic_serialization'=>true // включаем сериализацию данных
		);
		// задаем опции бэкэнда:
		$backendOptions = array('cache_dir'=>$config->path->cache);
		
		self::$_cacheCore = Zend_Cache::factory('Core',	'File',	$frontendOptions, $backendOptions);
		return self::$_cacheCore;
	}
	
	
	/**
	 * getCacheFile() - метод возвращяающий данные из кеша или заносящий их в кеш
	 * 
	 * @param $param	- 	параметр задающий тип кеширования
	 * 						Core (поумолчанию) - значит базовый, т.е. мы задаем время жизни кеша
	 * 						File - кеш обновится только если изменился сам файл источник данных
	 * 
	 * @param $master_file	-	имя файла изменение которого приводит к обновлению кеша
	 */
	static public function getCacheFile($masterFile)
	{
		// берем из реестра настройки конфигурации
		$config = Zend_Registry::get('config');
		
		// задаем опции фронтэнда:
		$frontendOptions = array(
			'master_file' => $masterFile, // указываем полные путь и имя главного файла
			'automatic_serialization' => true, // включаем сериализацию данных
			'lifetime' => null,	// устанавливаем бесконечное время жизни кеша если мастер-файл не изменился
			'write_control' => false 	// включение write_control немного замедлит запись кэша, 
										// но не чтение. Этот контроль поможет выявить некоторые 
										// поврежденные файлы кэша, но не является совершенным.
										// (в данном случае мы его отключили для увеличения производительности)
		);
		// задаем опции бэкэнда:
		$backendOptions = array(
			'cache_dir'=>$config->path->cache,
			'file_locking' => false // FIXME: it's ZF error (надо проверить может уже исправлено...)
		);
		
		return Zend_Cache::factory('File',	'File',	$frontendOptions, $backendOptions);
	}
	
	
	/**
	 * getCacheClass() - метод возвращяающий данные из кеша или заносящий их в кеш (для кеширования классов)
	 */
	static public function getCacheClass($className, $newInstance = null, $params = null)
	{
		// берем из реестра настройки конфигурации
		$config = Zend_Registry::get('config');
		// задаем опции фронтэнда:
			
		if ($newInstance == 'new') {
			// такой способ позволяет получать доступ к кэшированию обычных вызовов методов:
			$frontendOptions = array(
				'cached_entity' => new $className($params) // имя класса
			);
		} else if ($newInstance === null) {
			// такой способ позволяет получать доступ к кэшированию вызовов статических методов:
			$frontendOptions = array(
				'cached_entity' => $className // имя класса
			);
		}
			
		// задаем опции бэкэнда:
		$backendOptions = array(
			'cache_dir' => $config->path->cache // задаем где будет храниться кеш
			//'cache_dir' => 'application/cache'
		);
		// создаем кешируемый класса:
		$cacheClass = Zend_Cache::factory('Class',	'File',	$frontendOptions, $backendOptions);
		return $cacheClass;
	}
	
	/**
	 * setCache() - метод проверяет занесены ли данные в кеш, если нет то заносит их
	 * 				надо еще дорабатывать...
	 * 
	 * @param string $cacheId - название идентификатора под которым сохраняем данные в кеше
	 * @param string $pathToFile - строка содержащяа путь и имя кешируемого файла 
	 * 
	 * @return 
	 */
	/*static public function setCahe($file, $cacheId, $pathToFile)
	{
		if (!$cache = $cacheFileKld->load($cacheId)) {
			$cache = $emailTable->showEmailData($pathToFile);
			$cacheFileKld->save($cache, $cacheId); // кешируем данные
			return $cache;
		}
		else {
			return $cache;
		}
	}*/
	
		
	/**
	 * showDate($date) - метод отображаем даты в привычном формате: день.месяц.год часы:минуты:секунды
	 * 
	 * @param array $date - строка даты которую надо преобразовать в нужный вид
	 * 
	 * @return string $date
	 */
	static public function showDate($date)
	{
		$date = date_parse($date);
		$date['day'] = ($date['day'] < 10)? "0" . $date['day'] : $date['day'];
		$date['month'] = ($date['month'] < 10)? "0" . $date['month'] : $date['month'];
		$date['year'] = ($date['year'] < 10)? "0" . $date['year'] : $date['year'];
		$date['hour'] = ($date['hour'] < 10)? "0" . $date['hour'] : $date['hour'];
		$date['minute'] = ($date['minute'] < 10)? "0" . $date['minute'] : $date['minute'];
		$date['second'] = ($date['second'] < 10)? "0" . $date['second'] : $date['second'];
		
		return $date['day'] . "." . $date['month'] . "." . $date['year'] . "&nbsp;" . 
			$date['hour'] . ":" . $date['minute'] . ":" . $date['second'];
	}

	
	/**
	 *
	 * date_dif - метод расчета временного интервала между двумя переданными для сравнения датами
	 *
	 * @param string $date_completed - время окончания выполнения заявки 
	 * @param string $date_set - время назначения заявки,
	 *
	 */
	static public function dateDif($date_completed, $date_set)
	{ 
		$date_completed_array = date_parse($date_completed);
		$date_set_array = date_parse($date_set);
		
		// если получаем отрицательную разницу в секундах
		if($date_completed_array['second'] - $date_set_array['second'] < 0) { 
			$date_completed_array['minute'] = $date_completed_array['minute'] - 1;
			$date_completed_array['second'] = $date_completed_array['second'] + 60;
		}
		// если получаем отрицательную разницу в минутах
		if($date_completed_array['minute'] - $date_set_array['minute'] < 0) {  
			$date_completed_array['hour'] = $date_completed_array['hour'] - 1;
			$date_completed_array['minute'] = $date_completed_array['minute'] + 60;
		}
		// если получаем отрицательную разницу в часах
		if($date_completed_array['hour'] - $date_set_array['hour'] < 0) {  
			$date_completed_array['day'] = $date_completed_array['day'] - 1;
			$date_completed_array['hour'] = $date_completed_array['hour'] + 24;
		}
		// если получаем отрицательную разницу в днях
		if($date_completed_array['day'] - $date_set_array['day'] < 0) { 
			$dayInMonth = date("t"); // определяем количество дней в месяце
			$date_completed_array['month'] = $date_completed_array['month'] - 1;
			$date_completed_array['day'] = $date_completed_array['day'] + $dayInMonth;
		}
		// если получаем отрицательную разницу в месяцах
		if($date_completed_array['month'] - $date_set_array['month'] < 0) { 
			$date_completed_array['year'] = $date_completed_array['year'] - 1;
			$date_completed_array['month'] = $date_completed_array['month'] + 12;
		}
		
		$year_dif = $date_completed_array['year'] - $date_set_array['year'];
		$month_dif = $date_completed_array['month'] - $date_set_array['month'];
		$day_dif = $date_completed_array['day'] - $date_set_array['day'];
		$hour_dif = $date_completed_array['hour'] - $date_set_array['hour'];
		$minute_dif = $date_completed_array['minute'] - $date_set_array['minute'];
		$second_dif = $date_completed_array['second'] - $date_set_array['second'];
		
		$year_dif = ($year_dif == 0)? '' : $year_dif . 'г. ';
		$month_dif = ($month_dif == 0)? '' : $month_dif . 'мес. ';
		$day_dif = ($day_dif == 0)? '' : $day_dif . 'дн. ';
		$hour_dif = ($hour_dif == 0)? '' : $hour_dif . 'ч. ';
		$minute_dif = ($minute_dif == 0)? '' : $minute_dif . 'мин. ';
		$second_dif = ($second_dif == 0)? '' : $second_dif . 'сек.';
		
		if(
			($year_dif == '') && 
			($month_dif == '') && 
			($day_dif == '') && 
			($hour_dif == '') && 
			($minute_dif == '') && 
			($second_dif == '')
		) {
			return 0;
		} else if (
			($year_dif == '') && 
			($month_dif == '') && 
			($day_dif == '') && 
			($hour_dif == '') && 
			($minute_dif == '') && 
			($second_dif != '')
		) {
			return $second_dif;
		} else {
			return $year_dif . $month_dif . $day_dif . $hour_dif .	$minute_dif;
		}
	}

	
    /**
     * getIcoForExtention() - возвращает путь к пиктограмке для соответсвующего расширения файла
     * 
     * @param $ext - расширение файла
     * @param $baseUrl - базовый путь вида /kld-zft
     * 
     * @return string
     */
    public static function getIcon($ext, $baseUrl = '/kld-zft')
    {
    	$ext = strtolower($ext);
    	
    	return (isset(self::$_extArray["$ext"]))? 
    		$baseUrl . '/public/images/icons/' . self::$_extArray["$ext"][0] :
			$baseUrl . '/public/images/icons/' . self::$_extArray['default'][0];
    }
    
    /**
     * Функция возвращает mime тип по расширению файла, если неизвестное раширение,
     * то возвращается mime тип по-умолчанию
     */
    public static function getMimeType($filename)
    {
    	// TODO возвращает mime тип контента
		$pathInfo = pathinfo($filename);
		// определяем расширение файла
		$ext = (isset($pathInfo['extension']))? $pathInfo['extension'] : 'default';
		
		return (isset(self::$_extArray["$ext"]))? self::$_extArray["$ext"][1] : 
			self::$_extArray['default'][1];
    }
  
    
}


